<?php

namespace app\common\model;

use helper\ali\Pay as Alipay;
use helper\tencent\Pay as Wxpay;
use helper\tencent\QPay as Qpay;
use helper\union\Pay as Unionpay;
use helper\jd\Pay as Jdunipay;
use think\facade\Cache;

class Payment extends Base
{
    // 设置json类型字段
    protected $json = ['config'];

    // 设置JSON数据返回数组
    protected $jsonAssoc = true;

    /**
     * 配置信息
     * @param string $code
     * @param array $config
     * @return mixed
     */
    public static function config(string $code, array $config = [])
    {
        $name  = "config:$code";
        $cache = Cache::store('redis');
        if ($config) {
            $cache->set($name, self::handleConfig($config), 7200);
            return self::where('code', $code)->update(['config' => $config]);
        }
        $value = $cache->get($name);
        if (!$value) {
            $value = self::where('code', $code)->value('config');
            $value = $value ? self::handleConfig($value) : [];
            $cache->set($name, $value, 7200);
        }
        return $value;
    }

    /**
     * 键值对
     * @param array $config
     * @return array
     */
    private static function handleConfig(array $config): array
    {
        return array_column($config, 'value', 'name');
    }

    /**
     * alipay
     * @return Alipay
     */
    public static function alipay(): Alipay
    {
        $root_path = app()->getRootPath();
        $config = self::config('alipay');
        $config['notify_url'] = app()->request->domain() . '/notify/alipay';
        $config['app_cert_path'] = $root_path . $config['app_cert_path'];
        $config['alipay_cert_path'] = $root_path . $config['alipay_cert_path'];
        $config['root_cert_path'] = $root_path . $config['root_cert_path'];
        return new Alipay($config);
    }

    /**
     * wxpay
     * @return Wxpay
     */
    public static function wxpay(): Wxpay
    {
        $root_path = app()->getRootPath();
        $config = self::config('wxpay');
        $config['notify_url'] = app()->request->domain() . '/notify/wxpay';
        $config['private_key'] = $root_path . $config['private_key'];
        $config['public_key'] = $root_path . $config['public_key'];
        return new Wxpay($config);
    }

    public static function qpay()
    {
        $qqArr = array(
            "appid"      => "",
            "mch_id"     => "",
            "notify_url" => "",
            "key"        => "",
            "appKey"     => "",
        );
        return new Qpay($qqArr);
    }

    /**
     * Unionpay
     * @return Unionpay
     */
    public static function unionpay()
    {
        $root_path = app()->getRootPath();
        $config = self::config('unionpay');
        $config['mer_id'] = '777290058110048';
        $config['sign_cert_path'] = $root_path . 'cert/acp_test_sign.pfx';
        $config['sign_cert_pwd'] = '000000';
        $config['notify_url'] = app()->request->domain() . '/notify/unionpay';
        return new Unionpay($config);
    }

    /**
     * wxpay
     * @return Jdunipay
     */
    public static function jdunipay()
    {
        $root_path = app()->getRootPath();
        $config = self::config('jdunipay');
        $config['notify_url'] = app()->request->domain() . '/notify/jdunipay';
        return new Jdunipay($config);
    }

    /**
     * 转账
     * @return array
     */
    public static function transfer($user_id, $payment, $fee, $trade_no, $amount, $account, $name, $user_note)
    {
        // 调用支付
        switch ($payment) {
            case 4:
                $pay = self::alipay();
                break;
            case 5:
                $pay = self::wxpay();
                break;
            default:
                $pay = self::alipay();
        }
        $result = $pay->transfer($trade_no, $amount, $account, $name, $user_note);
        $user_note = $user_note ?? '';
        $remark = "收款人：{$account}（{$name}）；备注：" . $user_note . '；手续费：' . $fee . '；结果：' . $result['msg'];
        // 扣费并记录
        if ($result['status']) {
            User::change([
                'user_id' => $user_id,
                'account' => $account,
                'type'    => 1,
                'subject' => '余额提现',
                'remark'  => $remark,
                'fee'     => $fee
            ]);
            return ['out_trade_no'=> $trade_no];
        }
        return [];
    }

    /**
     * 提现
     *
     * @return void
     */
    public function withdraw()
    {

    }
}
